SGD

对权重执行带动量与权重衰减的随机梯度下降(SGD)更新,原地写回 weightaccumulate。 对区间 [start, end) 内元素逐点更新。

\[\begin{split}\begin{aligned} g'_t &= g_t + weight\_decay \cdot w_{t-1} \\ m_t &= moment \cdot m_{t-1} + (1 - dampening) \cdot g'_t \\ u_t &= \begin{cases} m_t \cdot moment + g'_t, & nesterov \neq 0 \\ m_t, & \text{otherwise} \end{cases} \\ w_t &= w_{t-1} - learning\_rate \cdot u_t \end{aligned}\end{split}\]

moment = 0 时,跳过动量累积,按 \(w_t = w_{t-1} - learning\_rate \cdot g'_t\) 更新。

输入:
  • weight - 待更新权重张量地址(输入/输出,原地更新)

  • accumulate - 动量累积张量地址(输入/输出,原地更新)

  • gradient - 梯度张量地址;weight_decay > 0 时会被原地改写为 \(g'_t\)

  • float_Parameters - 浮点超参数组,长度 4,布局见下

  • int_Parameters - 整数参数数组,长度 2,布局见下

  • nesterov - 是否启用 Nesterov 动量,取 0 / 非 0

  • core_mask - 核掩码(仅共享存储版本使用)

float_Parameters 布局:

  • [0] learning_rate - 学习率

  • [1] dampening - 动量阻尼系数

  • [2] moment - 动量系数

  • [3] weight_decay - 权重衰减系数

int_Parameters 布局:

  • [0] start - 参与计算的起始索引(含)

  • [1] end - 参与计算的结束索引(不含)

输出:
  • weight / accumulate - 原地写回更新结果

支持平台:

FT78NE MT7004

备注

  • FT78NE 支持 fp32

  • MT7004 支持 fp16、fp32

  • hp_ 版本中 float_Parameters 元素类型为 float16fp_ 版本为 float

  • weight_decay > 0 时会原地修改 gradient

共享存储版本:

void hp_sgd_s(float16 *weight, float16 *accumulate, float16 *gradient, float16 *float_Parameters, int *int_Parameters, int nesterov, int core_mask)
void fp_sgd_s(float *weight, float *accumulate, float *gradient, float *float_Parameters, int *int_Parameters, int nesterov, int core_mask)

C调用示例:

 1// MT7004 示例(共享存储多核,DDR 地址)
 2void TestSgdSMCFp32(int length, int core_mask) {
 3    int core_id = get_core_id();
 4    int logic_core_id = GetLogicCoreId(core_mask, core_id);
 5    int core_num = GetCoreNum(core_mask);
 6    float *weight = (float *)0x81000000;
 7    float *accumulate = (float *)0x90000000;
 8    float *gradient = (float *)0xA0000000;
 9    float *float_Parameters = (float *)0xE0000000;
10    int *int_Parameters = (int *)0xE0000010;
11    int nesterov = 0;
12    if (logic_core_id == 0) {
13        float_Parameters[0] = 0.01f;    // learning_rate
14        float_Parameters[1] = 0.1f;     // dampening
15        float_Parameters[2] = 0.9f;     // moment
16        float_Parameters[3] = 0.0001f;  // weight_decay
17        int_Parameters[0] = 0;          // start
18        int_Parameters[1] = length;    // end
19    }
20    sys_bar(0, core_num);
21    fp_sgd_s(weight, accumulate, gradient, float_Parameters, int_Parameters, nesterov, core_mask);
22}
23
24void main() {
25    int core_mask = 0b1111;
26    TestSgdSMCFp32(4096, core_mask);
27}

私有存储版本:

void hp_sgd_p(float16 *weight, float16 *accumulate, float16 *gradient, float16 *float_Parameters, int *int_Parameters, int nesterov)
void fp_sgd_p(float *weight, float *accumulate, float *gradient, float *float_Parameters, int *int_Parameters, int nesterov)

C调用示例:

 1// MT7004 示例(私有存储单核,AM 地址)
 2void TestSgdAMFp32(int length) {
 3    float *weight = (float *)0x10000000;
 4    float *accumulate = (float *)0x1002A800;
 5    float *gradient = (float *)0x10055000;
 6    float *float_Parameters = (float *)0x1007F000;
 7    int *int_Parameters = (int *)0x1007F010;
 8    int nesterov = 0;
 9    float_Parameters[0] = 0.01f;    // learning_rate
10    float_Parameters[1] = 0.1f;     // dampening
11    float_Parameters[2] = 0.9f;     // moment
12    float_Parameters[3] = 0.0001f;  // weight_decay
13    int_Parameters[0] = 0;          // start
14    int_Parameters[1] = length;    // end
15    fp_sgd_p(weight, accumulate, gradient, float_Parameters, int_Parameters, nesterov);
16}
17
18void main() {
19    TestSgdAMFp32(2048);
20}